﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Novel.Server.Models;
using Novel.Server.Response;
using System.Drawing.Printing;

namespace Novel.Server.Controllers
{
    /// <summary>
    /// 负责查询小说列表
    /// </summary>
    [Route("api/query")]
    [ApiController]
    public class ListController : ControllerBase
    {
        private readonly NovelContext dbContext;
        private readonly IConfiguration conf;

        public ListController(NovelContext context, IConfiguration configuration)
        {
            dbContext = context;
            conf = configuration;
        }

        private const int PageSize = 20;

        /// <summary>
        /// 获取所有小说
        /// </summary>
        [HttpGet("all")]
        public async Task<IActionResult> GetAllNovels([FromQuery] int page = 1)
        {
            var allMatch = dbContext.Novels
                .Where(n => !n.IsDeleted);
            return await FormatNovelList(allMatch, page);
        }

        /// <summary>
        /// 根据标签名获取小说列表
        /// </summary>
        [HttpGet("by_tag")]
        public async Task<IActionResult> GetNovelsByTag([FromQuery] string tag, [FromQuery] int page = 1)
        {
            var novelIds = await dbContext.Tags
                .Where(t => t.TagName == tag)
                .Select(t => t.NovelId)
                .Distinct()
                .ToListAsync();

            var allMatch = dbContext.Novels
                .Where(n => novelIds.Contains(n.NovelId) && !n.IsDeleted);

            return await FormatNovelList(allMatch, page);
        }

        /// <summary>
        /// 获取指定作者的小说
        /// </summary>
        [HttpGet("by_author/{authorId}")]
        public async Task<IActionResult> GetNovelsByAuthor(int authorId, [FromQuery] int page = 1)
        {
            var allMatch = dbContext.Novels
                .Where(n => n.AuthorId == authorId && !n.IsDeleted);

            return await FormatNovelList(allMatch, page);
        }

        /// <summary>
        /// 按标题关键字搜索小说
        /// </summary>
        [HttpGet("by_keyword")]
        public async Task<IActionResult> SearchNovelsByTitle([FromQuery] string keyword, [FromQuery] int page = 1)
        {
            var allMatch = dbContext.Novels
                .Where(n => !n.IsDeleted && EF.Functions.FreeText(n.Title, keyword));

            return await FormatNovelList(allMatch, page);
        }

        /// <summary>
        /// 搜索标签
        /// </summary>
        [HttpGet("tags")]
        public async Task<IActionResult> SearchTags([FromQuery] string keyword, [FromQuery] int page = 1)
        {
            var allMatch = dbContext.Tags
                .Where(t => EF.Functions.FreeText(t.TagName, keyword))
                .GroupBy(t => t.TagName)
                .Select(g => new
                {
                    tag_name = g.Key,
                    count = g.Count(),
                })
                .OrderByDescending(g => g.count)
                .ThenBy(g => g.tag_name);
            var tags = await allMatch.ToListAsync();

            return Ok(ApiResponse.SuccessResponse(new
            {
                tags = tags
            }));
        }

        /// <summary>
        /// 收藏列表
        /// </summary>
        [HttpGet("by_favorites")]
        [Authorize]
        public async Task<IActionResult> ListFavorites([FromQuery] int page = 1)
        {
            var username = User.Identity?.Name;
            var user = await dbContext.Users.FirstOrDefaultAsync(u => u.Username == username && !u.IsDeleted);
            if (user == null)
                return Unauthorized(ApiResponse.ErrorResponse("用户不存在", 401));

            var novelIds = await dbContext.Favorites
                .Where(f => f.UserId == user.UserId)
                .Select(f => f.NovelId)
                .Distinct()
                .ToListAsync();

            var allMatch = dbContext.Novels
                .Where(n => novelIds.Contains(n.NovelId) && !n.IsDeleted);
            
            return await FormatNovelList(allMatch, page);
        }

        private async Task<IActionResult> FormatNovelList(IQueryable<Models.Novel> query, int page)
        {
            var username = User.Identity?.Name;
            var user = username != null ? await dbContext.Users.FirstOrDefaultAsync(u => u.Username == username && !u.IsDeleted) : null;

            var allMatch = query
                .Include(n => n.Author)
                .OrderByDescending(n => n.UpdatedAt);

            var total = await allMatch.CountAsync();
            var novels = await allMatch
                .Skip((page - 1) * PageSize)
                .Take(PageSize).ToListAsync();
            var novelIds = novels.Select(n => n.NovelId);
            var favs = user != null ? await dbContext.Favorites
                .Where(f => f.UserId == user.UserId && novelIds.Contains(f.NovelId))
                .Select(f => f.NovelId).ToListAsync() : null;

            return Ok(ApiResponse.SuccessResponse(new
            {
                total = total,
                novels = novels.Select(n => new
                {
                    id = n.NovelId,
                    cover = n.Cover,
                    title = n.Title,
                    author = new
                    {
                        id = n.Author.UserId,
                        name = n.Author.Username,
                        avatar = n.Author.Avatar,
                        role = n.Author.Role,
                    },
                    is_favorite = favs?.Contains(n.NovelId) ?? false,
                })
            }));
        }
    }
}
